Day 15: Collections - List
The Java Collections Framework is a library of data structures for efficiently storing and managing data. Unlike arrays, collections dynamically resize and provide various utility methods. Today we focus on the most commonly used List interface.
ArrayList Basics
An array-based list with fast index-based access as its strength.
import java.util.ArrayList;
import java.util.List;
public class ArrayListBasic {
public static void main(String[] args) {
// Create an ArrayList
List<String> fruits = new ArrayList<>();
// Add elements
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Grape");
fruits.add("Strawberry");
// Add at a specific position
fruits.add(1, "Orange");
// Access elements
System.out.println("First: " + fruits.get(0)); // Apple
System.out.println("Size: " + fruits.size()); // 5
System.out.println("Contains Grape? " + fruits.contains("Grape")); // true
System.out.println("Grape index: " + fruits.indexOf("Grape")); // 3
// Modify an element
fruits.set(0, "Green Apple");
// Remove elements
fruits.remove("Banana"); // Remove by value
fruits.remove(0); // Remove by index
// Iteration methods
// 1. for-each
for (String fruit : fruits) {
System.out.print(fruit + " ");
}
System.out.println();
// 2. forEach + lambda
fruits.forEach(fruit -> System.out.print(fruit + " "));
System.out.println();
// Check if empty
System.out.println("Is empty? " + fruits.isEmpty());
// Clear all
fruits.clear();
System.out.println("Size after clear: " + fruits.size());
}
}
ArrayList vs LinkedList
Learn how to choose the appropriate list implementation for different situations.
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ListComparison {
public static void main(String[] args) {
// ArrayList: uses an array internally
// - Index access: O(1) fast
// - Middle insert/delete: O(n) slow (element shifting required)
List<Integer> arrayList = new ArrayList<>();
// LinkedList: uses a doubly linked list internally
// - Index access: O(n) slow
// - Front/back insert/delete: O(1) fast
List<Integer> linkedList = new LinkedList<>();
// Performance comparison: adding data
long start;
// ArrayList: add to end
start = System.nanoTime();
for (int i = 0; i < 100000; i++) {
arrayList.add(i);
}
System.out.println("ArrayList append: " +
(System.nanoTime() - start) / 1_000_000 + "ms");
// LinkedList: add to end
start = System.nanoTime();
for (int i = 0; i < 100000; i++) {
linkedList.add(i);
}
System.out.println("LinkedList append: " +
(System.nanoTime() - start) / 1_000_000 + "ms");
// Index access comparison
start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
arrayList.get(50000);
}
System.out.println("ArrayList index access: " +
(System.nanoTime() - start) / 1_000_000 + "ms");
start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
linkedList.get(50000);
}
System.out.println("LinkedList index access: " +
(System.nanoTime() - start) / 1_000_000 + "ms");
// Conclusion: use ArrayList in most cases
// LinkedList only when frequent insert/delete at front/back
}
}
List Sorting and Searching
Sorting with Collections utility and Comparator.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ListSortSearch {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>(List.of(38, 27, 43, 3, 9, 82, 10));
// Ascending sort
Collections.sort(numbers);
System.out.println("Ascending: " + numbers);
// Descending sort
numbers.sort(Comparator.reverseOrder());
System.out.println("Descending: " + numbers);
// String list sorting
List<String> names = new ArrayList<>(List.of("Alice", "Charlie", "Bob", "Diana"));
// Lexicographic sort
Collections.sort(names);
System.out.println("Alphabetical: " + names);
// Sort by length
names.sort(Comparator.comparingInt(String::length));
System.out.println("By length: " + names);
// Immutable list creation
List<String> immutable = List.of("A", "B", "C");
// immutable.add("D"); // UnsupportedOperationException!
// Copying a list
List<String> copied = new ArrayList<>(immutable);
copied.add("D"); // OK
// Useful methods
System.out.println("Max: " + Collections.max(numbers));
System.out.println("Min: " + Collections.min(numbers));
System.out.println("Frequency: " + Collections.frequency(numbers, 10));
// Sublist
List<Integer> sub = numbers.subList(1, 4);
System.out.println("Sublist: " + sub);
}
}
Practical Example: Student Management System
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
record Student(String name, int score, String grade) implements Comparable<Student> {
@Override
public int compareTo(Student other) {
return Integer.compare(other.score, this.score); // Descending by score
}
}
public class StudentManager {
private final List<Student> students = new ArrayList<>();
void addStudent(String name, int score) {
String grade = switch (score / 10) {
case 10, 9 -> "A";
case 8 -> "B";
case 7 -> "C";
default -> score >= 60 ? "D" : "F";
};
students.add(new Student(name, score, grade));
}
void printAll() {
System.out.println("=== All Students ===");
students.forEach(s ->
System.out.printf("%-10s %3d pts (%s)%n", s.name(), s.score(), s.grade()));
}
void printSorted() {
System.out.println("=== By Score ===");
students.stream()
.sorted()
.forEach(s -> System.out.printf("%-10s %3d pts%n", s.name(), s.score()));
}
double getAverage() {
return students.stream()
.mapToInt(Student::score)
.average()
.orElse(0.0);
}
public static void main(String[] args) {
StudentManager manager = new StudentManager();
manager.addStudent("Alice", 85);
manager.addStudent("Bob", 92);
manager.addStudent("Charlie", 78);
manager.addStudent("Diana", 95);
manager.addStudent("Eve", 88);
manager.printAll();
manager.printSorted();
System.out.printf("Overall average: %.1f pts%n", manager.getAverage());
}
}
Today’s Exercises
-
To-Do List Manager: Create a ToDo list using
ArrayList. Implement add, delete (by index), mark as complete, print all items, and filter only completed items. -
Remove Duplicates: Write a method that removes duplicates from an integer list while maintaining the original order. (Implement using only List, without Set)
-
Multi-Sort Students: Create Comparators to sort a
Studentobject list by name, score, and grade respectively. Also implement a composite sort that sorts by name when scores are equal.